# -*- coding: UTF-8 -*-
from PCV.tools import imtools, pca
from PIL import Image, ImageDraw
from PCV.localdescriptors import sift
from pylab import *
import glob
import os
from scipy.cluster.vq import *

# list of downloaded filenames
imlist = imtools.get_imlist('G:/TestResportsGeneration/screenshots/')
nbr_images = len(imlist)
print nbr_images

# extract features
for i in range(nbr_images):
    im = Image.open(imlist[i]).convert('L')
    im.save('G:/TestResportsGeneration/screenshots/' + 'tmp' + '.pgm')
    imagename = imlist[i].replace('G:/TestResportsGeneration/screenshots/', '')
    imagename = imagename.replace('.jpg', '')
    cmmd = str(
        "C:/Python27/Lib/sift.exe G:/TestResportsGeneration/screenshots/" + "tmp.pgm --output=G:/TestResportsGeneration/screenshots/" + imagename + ".sift --edge-thresh 10 --peak-thresh 5")
    os.system(cmmd)

featlist = glob.glob('G:/TestResportsGeneration/screenshots/*.sift')
matchscores = zeros((nbr_images, nbr_images))
print featlist


def distance(feat1, feat2):
    l1, d1 = sift.read_features_from_file(feat1)
    l2, d2 = sift.read_features_from_file(feat2)
    matches = sift.match_twosided(d1, d2)
    matches = sum(matches > 0)
    return matches


for i in range(nbr_images):
    for j in range(i, nbr_images):  # only compute upper triangle
        print 'comparing ', imlist[i], imlist[j]
        nbr_matches = distance(featlist[i], featlist[j])
        print 'number of matches = ', nbr_matches
        matchscores[i, j] = nbr_matches
print "The match scores is: \n", matchscores

# copy values
for i in range(nbr_images):
    for j in range(i + 1, nbr_images):  # no need to copy diagonal
        matchscores[j, i] = matchscores[i, j]
print "The match scores is: \n", matchscores

n = len(imlist)
# load the similarity matrix and reformat
S = matchscores
S = 1 / (S + 1e-6)

# create Laplacian matrix
rowsum = sum(S, axis=0)
D = diag(1 / sqrt(rowsum))
I = identity(n)
L = I - dot(D, dot(S, D))
# compute eigenvectors of L
U, sigma, V = linalg.svd(L)
k = 4
# create feature vector from k first eigenvectors
# by stacking eigenvectors as columns
features = array(V[:k]).T
# k-means
features = whiten(features)
centroids, distortion = kmeans(features, k)
code, distance = vq(features, centroids)
# plot clusters
for c in range(k):
    ind = where(code == c)[0]
    figure()
    gray()
    for i in range(minimum(len(ind), 39)):
        im = Image.open(imlist[ind[i]])
        subplot(4, 10, i + 1)
        imshow(array(im))
        axis('equal')
        axis('off')
show()
